import numpy as np
import sys
sys.path.append('../mobilepy')
sys.path.append('../rtlusrtos')

import lte.lte as lte
from rtlusrtos.interface.rtl import RTLInterface
from rtlusrtos.interface.interface import View
from rtlusrtos.rtl.ftcommap import rx
from lte.refsignal import LazyReferences
from lte.phy import Phy

import config
class LTE:
    refs = LazyReferences()
    def __init__(self,rx_ports):
        self.rx_ports = rx_ports
        self.lte = [lte.LTE(rx(config,port_id)) for port_id in range(self.rx_ports)]
        self.fi = [RTLInterface(874.2e6,l) for l in self.lte]
        self.view = [ View(fi) for fi in self.fi]
        self.ioc = []
    def start(self):
        for v in self.view:
            v.reset()
        # self.run()
    def run(self):
        rfd = [v.raw(0,2) for v in self.view]
        for v in self.view:
            v.run(1)
        rx_symbols = [Phy.ofdm_rx(r[9600:9600+19200],6) for r in rfd]
        n = len(self.ioc)
        res = np.zeros((128,self.rx_ports,n),dtype=complex)
        for i in range(n):
            res[:,:,i] = self.calc(rx_symbols,i)
        return res,rx_symbols
    
    def calc(self,rx_symbols,i):
        tx_tab = self.ioc[i]
        res = np.zeros((128,self.rx_ports),dtype=complex)
        for p in range(self.rx_ports):
            res[:,p] = Phy.pick_pilot(rx_symbols[p],tx_tab)
        for i in range(self.rx_ports):
            res[:,i] = np.fft.fftshift(np.fft.ifft(res[:,i]))
        return res

def antanna(pos,phi,l,d):
    n = int(180/d)
    d = np.zeros((2*n,n),dtype=complex)
    for i in range(2*n):
        psi = i/(2*n)*2*np.pi
        for j in range(n):
            theta = j/n*np.pi
            d[i,j] = np.cos(theta)*np.exp(1j*psi)
    s = np.zeros((2*n,n),dtype=complex)
    for i in range(len(pos)):
        pj = pos[i]*np.conj(d)
        s += np.exp(1j*(pj.real/l*2*np.pi+phi[i]))
    sl = np.abs(s)
    X,Y,Z = [],[],[]
    for i in range(2*n):
        psi = i/(2*n)*2*np.pi
        for j in range(n):
            theta = j/n*np.pi
            z = np.sin(theta)
            x = np.cos(psi)*np.cos(theta)
            y = np.sin(psi)*np.cos(theta)
            X.append(x*sl[i,j])
            Y.append(y*sl[i,j])
            Z.append(z*sl[i,j])
    return X,Y,Z